home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 001-025 / disk_008 / src / hack.vault.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  5KB  |  216 lines

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
  2.  
  3. #include    "hack.h"
  4. #ifdef QUEST
  5. setgd(/* mtmp */) /* struct monst *mtmp; */ {}
  6. gd_move() { return(2); }
  7. gddead(mtmp) struct monst *mtmp; {}
  8. invault(){}
  9.  
  10. #else
  11.  
  12.  
  13. extern struct monst *makemon();
  14. #define    VAULT    6
  15. #define    FCSIZ    (ROWNO+COLNO)
  16. struct fakecorr {
  17.     xchar fx,fy,ftyp;
  18. };
  19.  
  20. struct egd {
  21.     int fcbeg, fcend;    /* fcend: first unused pos */
  22.     xchar gdx, gdy;        /* goal of guard's walk */
  23.     unsigned gddone:1;
  24.     struct fakecorr fakecorr[FCSIZ];
  25. };
  26.  
  27. struct permonst pm_guard =
  28.     { "guard", '@', 12, 12, -1, 4, 10, sizeof(struct egd) };
  29.  
  30. struct monst *guard;
  31. int gdlevel;
  32. #define    EGD    ((struct egd *)(&(guard->mextra[0])))
  33.  
  34. restfakecorr(){
  35. register int fcx,fcy,fcbeg;
  36. register struct rm *crm;
  37.  
  38.     while((fcbeg = EGD->fcbeg) < EGD->fcend) {
  39.         fcx = EGD->fakecorr[fcbeg].fx;
  40.         fcy = EGD->fakecorr[fcbeg].fy;
  41.         if((u.ux == fcx && u.uy == fcy) || cansee(fcx,fcy) ||
  42.            m_at(fcx,fcy))
  43.             return;
  44.         crm = &levl[fcx][fcy];
  45.         crm->typ = EGD->fakecorr[fcbeg].ftyp;
  46.         if(!crm->typ) crm->seen = 0;
  47.         newsym(fcx,fcy);
  48.         EGD->fcbeg++;
  49.     }
  50.     /* it seems he left the corridor - let the guard disappear */
  51.     mondead(guard);
  52.     guard = 0;
  53. }
  54.  
  55. setgd(){
  56. register struct monst *mtmp;
  57.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) if(mtmp->isgd){
  58.         guard = mtmp;
  59.         gdlevel = dlevel;
  60.         return;
  61.     }
  62.     guard = 0;
  63. }
  64.  
  65. invault(){
  66. register int tmp = inroom(u.ux, u.uy);
  67.     if(tmp < 0 || rooms[tmp].rtype != VAULT) {
  68.         u.uinvault = 0;
  69.         return;
  70.     }
  71.     if(++u.uinvault % 50 == 0 && (!guard || gdlevel != dlevel)) {
  72.     char buf[BUFSZ];
  73.     register int x,y,dx,dy,gx,gy;
  74.  
  75.         /* first find the goal for the guard */
  76.         for(dy = 0; dy < ROWNO; dy++)
  77.           for(y = u.uy-dy; y <= u.uy+dy; y++) {
  78.             if(y > u.uy-dy) y = u.uy+dy;
  79.             if(y < 0 || y > ROWNO-1) continue;
  80.             for(x = u.ux; x < COLNO; x++)
  81.             if(levl[x][y].typ == CORR) goto fnd;
  82.             for(x = u.ux-1; x > 0; x--)
  83.             if(levl[x][y].typ == CORR) goto fnd;
  84.         }
  85.         impossible();
  86.         tele();
  87.         return;
  88.     fnd:
  89.         gx = x; gy = y;
  90.  
  91.         /* next find a good place for a door in the wall */
  92.         x = u.ux; y = u.uy;
  93.         while(levl[x][y].typ > DOOR) {
  94.             dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
  95.             dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
  96.             if(abs(gx-x) >= abs(gy-y)) x += dx;
  97.             else y += dy;
  98.         }
  99.  
  100.         /* make something interesting happen */
  101.         if(!(guard = makemon(&pm_guard,x,y))) return;
  102.         guard->isgd = guard->mpeaceful = 1;
  103.         EGD->gddone = 0;
  104.         gdlevel = dlevel;
  105.         if(!cansee(guard->mx, guard->my)) {
  106.             mondead(guard);
  107.             guard = 0;
  108.             return;
  109.         }
  110.         EGD->gdx = gx;
  111.         EGD->gdy = gy;
  112.         EGD->fcbeg = 0;
  113.         EGD->fakecorr[0].fx = x;
  114.         EGD->fakecorr[0].fy = y;
  115.         EGD->fakecorr[0].ftyp = levl[x][y].typ;
  116.         levl[x][y].typ = DOOR;
  117.         EGD->fcend = 1;
  118.  
  119.         pline("Suddenly one of the Vault's guards enters!");
  120.         pmon(guard);
  121.         pline("\"Hello stranger, who are you?\" - ");
  122.         getlin(buf);
  123.         clrlin();
  124.         pline("\"I don't know you.\"");
  125.         if(!u.ugold) pline("\"Please follow me.\"");
  126.         else {
  127.             pline("\"Most likely all that gold was stolen from this vault.\"");
  128.             pline("\"Please drop your gold (say d$ ) and follow me.\"");
  129.         }
  130.     }
  131. }
  132.  
  133. gd_move(){
  134. register int x,y,dx,dy,gx,gy,nx,ny,tmp;
  135. register struct fakecorr *fcp;
  136. register struct rm *crm;
  137.     if(!guard || gdlevel != dlevel){
  138.         pline("Where is the guard?");
  139.         impossible();
  140.         return(2);    /* died */
  141.     }
  142.     if(u.ugold || dist(guard->mx,guard->my) > 2 || EGD->gddone){
  143.         restfakecorr();
  144.         return(0);    /* didnt move */
  145.     }
  146.     x = guard->mx;
  147.     y = guard->my;
  148.     /* look around (hor & vert only) for accessible places */
  149.     for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++)
  150.         if(nx == x || ny == y) if(nx != x || ny != y)
  151.         if(isok(nx,ny))
  152.         if((tmp = (crm = &levl[nx][ny])->typ) >= SDOOR) {
  153.         register int i;
  154.         for(i = EGD->fcbeg; i < EGD->fcend; i++)
  155.             if(EGD->fakecorr[i].fx == nx &&
  156.                EGD->fakecorr[i].fy == ny)
  157.                 goto nextnxy;
  158.         if((i = inroom(nx,ny)) >= 0 && rooms[i].rtype == VAULT)
  159.             goto nextnxy;
  160.         /* seems we found a good place to leave him alone */
  161.         EGD->gddone = 1;
  162.         if(tmp >= DOOR) goto newpos;
  163.         crm->typ = (tmp == SCORR) ? CORR : DOOR;
  164.         goto proceed;
  165.     nextnxy:    ;
  166.     }
  167.     nx = x;
  168.     ny = y;
  169.     gx = EGD->gdx;
  170.     gy = EGD->gdy;
  171.     dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
  172.     dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
  173.     if(abs(gx-x) >= abs(gy-y)) nx += dx; else ny += dy;
  174.  
  175.     while((tmp = (crm = &levl[nx][ny])->typ) != 0) {
  176.     /* in view of the above we must have  tmp < SDOOR */
  177.     /* must be a wall here */
  178.         if(isok(nx+nx-x,ny+ny-y) && levl[nx+nx-x][ny+ny-y].typ > DOOR){
  179.             crm->typ = DOOR;
  180.             goto proceed;
  181.         }
  182.         if(dy && nx != x) {
  183.             nx = x; ny = y+dy; dx = 0;
  184.             continue;
  185.         }
  186.         if(dx && ny != y) {
  187.             ny = y; nx = x+dx; dy = 0;
  188.             continue;
  189.         }
  190.         /* I don't like this, but ... */
  191.         crm->typ = DOOR;
  192.         goto proceed;
  193.     }
  194.     crm->typ = CORR;
  195. proceed:
  196.     fcp = &(EGD->fakecorr[EGD->fcend]);
  197.     if(EGD->fcend++ == FCSIZ) panic("fakecorr overflow");
  198.     fcp->fx = nx;
  199.     fcp->fy = ny;
  200.     fcp->ftyp = tmp;
  201. newpos:
  202.     if(EGD->gddone) nx = ny = 0;
  203.     guard->mx = nx;
  204.     guard->my = ny;
  205.     pmon(guard);
  206.     restfakecorr();
  207.     return(1);
  208. }
  209.  
  210. gddead(){
  211.     guard = 0;
  212. }
  213.  
  214.  
  215. #endif QUEST
  216.